﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
// 原题连接：https://leetcode.cn/problems/kth-smallest-element-in-a-sorted-matrix/
/*
题目描述：
给你一个 n x n 矩阵 matrix ，其中每行和每列元素均按升序排序，找到矩阵中第 k 小的元素。
请注意，它是 排序后 的第 k 小元素，而不是第 k 个 不同 的元素。
你必须找到一个内存复杂度优于 O(n2) 的解决方案。


示例 1：
输入：matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8
输出：13
解释：矩阵中的元素为 [1,5,9,10,11,12,13,13,15]，第 8 小元素是 13

示例 2：
输入：matrix = [[-5]], k = 1
输出：-5
 

提示：
n == matrix.length
n == matrix[i].length
1 <= n <= 300
-109 <= matrix[i][j] <= 109
题目数据 保证 matrix 中的所有行和列都按 非递减顺序 排列
1 <= k <= n2
 

进阶：
你能否用一个恒定的内存(即 O(1) 内存复杂度)来解决这个问题?
你能在 O(n) 的时间复杂度下解决这个问题吗?这个方法对于面试来说可能太超前了，但是你会发现阅读这篇文章（ this paper ）很有趣。
*/

// 开始解题：
// 方法1——暴力拷贝+排序法
// 先写一个函数，比较两个整数的大小
int cmp_int(const void* p1, const void* p2) {
    assert(p1 && p2);
    return *((int*)p1) - *((int*)p2);
}
int kthSmallest(int** matrix, int matrixSize, int* matrixColSize, int k) {
    // 先开辟一个数组，将矩阵中的元素都拷贝过去
    int* array = (int*)malloc((matrixSize * (*matrixColSize)) * sizeof(int));
    if (NULL == array) {
        perror("malloc fail");
        return -1;
    }
    // 将矩阵中的元素拷贝到数组中
    int i = 0;
    int j = 0;
    int n = 0;
    for (i = 0; i < matrixSize; i++) {
        for (j = 0; j < *matrixColSize; j++) {
            array[n] = matrix[i][j];
            n++;
        }
    }
    // 再对数组进行排序
    qsort(array, matrixSize * (*matrixColSize), sizeof(int), cmp_int);
    int answer = array[k - 1];
    free(array);
    array = NULL;
    return answer;
}
// 时间复杂度：O(n^2)，n为矩阵的边长。
// 空间复杂度：O(n^2)，我们需要额外的n*n整型空间来存储矩阵中的元素。